<?php

    /*$A[0][0] = 0.5;
    $A[0][1] = -2.8;
    $A[1][0] = 0.75;
    $A[1][1] = -0.6;
    $A[2][0] = 1;
    $A[2][1] = 1;
    $A[3][0] = 1.5;
    $A[3][1] = 3.2;
    $A[4][0] = 2;
    $A[4][1] = 4.8;
    $A[5][0] = 2.5;
    $A[5][1] = 6;
    $A[6][0] = 3;
    $A[6][1] = 7;*/

    /*$A[0][0] = 1; $A[0][1] = 0.5;
    $A[1][0] = 2; $A[1][1] = 0.6;
    $A[2][0] = 3; $A[2][1] = 0.9;
    $A[3][0] = 4; $A[3][1] = 0.8;
    $A[4][0] = 5; $A[4][1] = 1.2;
    $A[5][0] = 6; $A[5][1] = 1.5;
    $A[6][0] = 7; $A[6][1] = 1.7;
    $A[7][0] = 8; $A[7][1] = 2;*/

    $A[0][0] = -2; $A[0][1] = 0;
    $A[1][0] = -1; $A[1][1] = 1;
    $A[2][0] = 0;  $A[2][1] = 2;
    $A[3][0] = 1;  $A[3][1] = 1;
    $A[4][0] = 2;  $A[4][1] = 0;

    echo minimos_ortogonais($A, 4, 2);

class Polinomio
{
    private $polinomio;
    public function __construct($grau=0)
    {
        for ($i = 0; $i <= $grau; $i++)
        {
            $this->polinomio[$i] = 0;
        }
    }
    public function __destruct()
    {
    }
    public function set($n,$valor)
    {
        $this->polinomio[$n] = $valor;
    }
    public function get()
    {
        return $this->polinomio;
    }
    public function soma($polinomio)
    {
        foreach ($polinomio->get() as $ind => $p)
        {
            if (isset($this->polinomio[$ind]))
                $this->polinomio[$ind] += $p;
            else
                $this->polinomio[$ind] = $p;
        }
    }
    public function mult($valor)
    {
        foreach ($this->polinomio as $ind => $p)
        {
            $this->polinomio[$ind] = $p * $valor;
        }
    }
    public function ev($valor)
    {
        $soma = 0;
        foreach ($this->polinomio as $ind => $p)
        {
            $soma+=$p * pow($valor,$ind);
        }
        return $soma;
    }
    public function cp($poli)
    {
        foreach ($poli->get() as $ind => $p)
        {
            $this->polinomio[$ind] = $p;
        }
    }
    public function str()
    {
        $str = "";
        foreach ($this->polinomio as $ind => $p)
        {
            if ($p > 0)
                $str.= "+";
            if ($p != 0)
                $str.= (($p != 1)?$p:'').(($ind!=0)?("x<sup>".$ind."</sup>"):'');
        }
        if (empty($str)) $str = '0';
        return $str;
    }
}

function minimos_ortogonais($matriz, $grau, $valor)
{
    $output="<p>Calculando os polinomios ortogonais:</p>";
    $phi[0] = new Polinomio();
    $phi[0]->set(0,1);
    for ($i = 1 ; $i <= $grau; $i++)
    {
        $output.="<p>Calculando phi<sub>$i</sub>(x)</p>";
        //somatorio
        $soma = new Polinomio();
        for ($k = 0; $k < $i; $k++)
        {
            $soma1 = 0;
            $soma2 = 0;
            for ($n = 0; $n < count($matriz); $n++)
            {
                $x = $matriz[$n][0];
                $aux = new Polinomio();
                $aux->set($i,1);
                $soma1+=$aux->ev($x)*$phi[$k]->ev($x);
                $soma2+=pow($phi[$k]->ev($x),2);
            }
            $output.="<p>alfa($i,$k)=$soma1/$soma2</p>";
            $somatorio = new Polinomio();
            $somatorio->cp($phi[$k]);
            $somatorio->mult(-$soma1/$soma2);
            $soma->soma($somatorio);
        }
        $phi[$i] = new Polinomio($i);
        $phi[$i]->set($i,1);
        $phi[$i]->soma($soma);
        $output.="<p>phi<sub>$i</sub>(x)=".$phi[$i]->str()."</p>";
    }
    $output.="Calculando a<sub>n</sub>*phi<sub>n</sub>:";
    for ($x = 0; $x <= $grau; $x++)
    {
        $soma1 = 0;
        $soma2 = 0;
        for ($n = 0; $n < count($matriz); $n++)
        {
            $soma1+=$matriz[$n][1]*$phi[$x]->ev($matriz[$n][0]);
            $soma2+=pow($phi[$x]->ev($matriz[$n][0]),2);
        }
        $termos[$x] = new Polinomio();
        $termos[$x]->cp($phi[$x]);
        $termos[$x]->mult( ($soma1/$soma2) );
        $output.="<p>a<sub>$x</sub> = ".($soma1/$soma2)."</p>";
        $output.="<p>phi<sub>$x</sub> = ".$phi[$x]->str()."</p>";
        $output.="<p>a<sub>$x</sub>*phi<sub>$x</sub> = ".$termos[$x]->str()."</p>";
        //echo $soma1." / ".$soma2."<br>";
    }
    $polinomio = new Polinomio();
    foreach ($termos as $t)
    {
        $polinomio->soma($t);
    }
    /*$polinomio->disp();
    echo "<br>";*/
    //echo $polinomio->ev($valor);
    echo $output;
}
?>